package com.adl.telawa;

import com.adl.telawa.utils.WatchDog;

import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.util.Log;
import android.widget.ProgressBar;

/**
 * @author Adlane Achab.
 */
public class Streamer implements OnBufferingUpdateListener, OnCompletionListener, OnErrorListener, OnPreparedListener, OnInfoListener, OnSeekCompleteListener
{
	private final class RefreshProgressBar extends Thread
	{
		@Override
		public void run() {
			while (true)
			{
				try {
					while (_state == STATE_STARTED && _mp != null)
					{
						if (_mp.getDuration() > 0)
							_progressBar.setProgress((_mp.getCurrentPosition() * 100 / _mp.getDuration()) + 1);

						sleep(500);
					}
					sleep(1000);
				} catch (Throwable e) {}
			}
		}
	};

	private static final int STATE_NONE        = -1;
	private static final int STATE_IDLE        =  0;
	private static final int STATE_INITIALIZED =  1;
	private static final int STATE_PREPARED    =  2;
	private static final int STATE_STARTED     =  3;
	private static final int STATE_PAUSED      =  4;
	private static final int STATE_STOPPED     =  5;
	private static final int STATE_END         =  6;

	private MediaPlayer _mp;
	private ProgressBar _progressBar;
	private RefreshProgressBar _refreshProgressBar;
	private int _state = STATE_NONE;

	public Streamer()
	{
		_mp = null;
		_state = STATE_IDLE;
		_refreshProgressBar = new RefreshProgressBar();
		_refreshProgressBar.start();
	}

	private void init()
	{
		_mp = new MediaPlayer();
		_state = STATE_IDLE;
		_mp.setOnBufferingUpdateListener(this);
		_mp.setOnCompletionListener(this);
		_mp.setOnErrorListener(this);
		_mp.setOnInfoListener(this);
		_mp.setOnPreparedListener(this);
		_mp.setOnSeekCompleteListener(this);
	}

	public void init(final ProgressBar progressBar)
	{
		_progressBar = progressBar;
	}

	public synchronized void startStreaming(final String url)
	{
		new Thread("Streamer.Thread") {
			public void run()
			{
				WatchDog.INSTANCE.remove();

				if (_mp != null) {
					try {
						_mp.stop();
						_mp.release();
						_mp = null;    
					} catch (Throwable e) {}
				}

				Log.v("Streamer", "startStreaming");

				try
				{
					WatchDog.INSTANCE.set(this, 30000);
					init();

					_mp.reset();
					_state = STATE_IDLE;
					_mp.setDataSource(url);
					_state = STATE_INITIALIZED;
					_mp.prepare();
				}
				catch (Throwable e) {
					e.printStackTrace();
					Initial.INSTANCE.info("Telawa: Read error");
				}
			}
		}.start();
	}

	public synchronized void start()
	{
		if (_mp == null) return;

		try
		{
			Log.v("Streamer", "start");
			if (_state == STATE_PAUSED ||
					_state == STATE_PREPARED ||
					_state == STATE_END ||
					_state == STATE_STARTED)
			{
				WatchDog.INSTANCE.remove();

				_mp.start();
				_state = STATE_STARTED;
			}
		}
		catch(Throwable e){}
	}

	public synchronized void stop()
	{
		if (_mp == null) return;

		try
		{
			Log.v("Streamer", "stop");
			if (_state == STATE_PAUSED ||
					_state == STATE_PREPARED ||
					_state == STATE_STOPPED ||
					_state == STATE_END ||
					_state == STATE_STARTED)
			{
				_mp.stop();
				_state = STATE_STOPPED;
			}
		}
		catch (Throwable e){}
	}

	public synchronized boolean isPlaying()
	{
		if (_mp == null) return false;
		return _state == STATE_STARTED;
	}

	public synchronized void pause()
	{
		if (_mp == null) return;

		try
		{
			Log.v("Streamer", "pause");
			if (_state == STATE_PAUSED ||
					_state == STATE_STARTED) {
				_mp.pause();
				_state = STATE_PAUSED;
			}
		}
		catch(Throwable e){}
	}

	public synchronized void forward()
	{
		if (_mp == null) return;

		try
		{
			Log.v("Streamer", "forward");
			if (_state == STATE_STARTED) {
				int pos = (_mp.getDuration() * 5 / 100) + _mp.getCurrentPosition() ;
				_mp.seekTo(pos);
			}
		}
		catch(Throwable e){}
	}

	public synchronized void backward()
	{
		if (_mp == null) return;

		try
		{
			Log.v("Streamer", "backward");
			if (_state == STATE_STARTED) {
				int pos = -(_mp.getDuration() * 5 / 100) + _mp.getCurrentPosition() ;
				_mp.seekTo(pos);
			}
		}
		catch(Throwable e){}
	}

	/** ---------------------------------------------------- listeners ---------------------------------------------------**/

	@Override
	public void onBufferingUpdate(MediaPlayer arg0, int per) {
		Log.v("Streamer", "Downloading " + per + "%");
		_progressBar.setSecondaryProgress(per);
	}

	@Override
	public void onCompletion(MediaPlayer arg0) {
		Log.v("Streamer", "Completed");
		_state = STATE_END;
		if (_mp != null)
			_mp.release();
		MyListAdapter.INSTANCE.nextSurat();
	}

	@Override
	public boolean onError(MediaPlayer arg0, int what, int extra) {
		Log.v("Streamer", "Error  what:" + what + " extra:" + extra);
		return true;
	}

	@Override
	public boolean onInfo(MediaPlayer arg0, int what, int extra) {
		Log.v("Streamer", "Info  what:" + what + " extra:" + extra);
		return false;
	}

	@Override
	public void onPrepared(MediaPlayer arg0) {
		Log.v("Streamer", "Prepared, start now.");
		_state = STATE_PREPARED;
		start();
	}

	@Override
	public void onSeekComplete(MediaPlayer arg0) {
		Log.v("Streamer", "Seek completed.");
	}
}
